﻿using System;
using System.Linq;
using Eagles.Base;
using Eagles.DomainService.Model.User;
using Eagles.Interface.Core.Study;
using Eagles.Interface.DataAccess.Util;
using Eagles.Interface.DataAccess.NewsDa;
using Eagles.Interface.DataAccess.StudyAccess;
using Eagles.Application.Model;
using Eagles.Application.Model.Study.EditStudyTime;
using Eagles.Application.Model.Study.GetStudyTime;
using Eagles.Application.Model.Study.GetUserStudy;
using Eagles.Application.Model.Study.GetUserStudyDetail;

namespace Eagles.DomainService.Core.Study
{
    public class StudyHandler : IStudyHandler
    {
        private readonly IStudyAccess iStudyAccess;
        private readonly INewsDa iNewsDa;
        private readonly IUtil util;

        public StudyHandler(IStudyAccess iStudyAccess, INewsDa iNewsDa, IUtil util)
        {
            this.iStudyAccess = iStudyAccess;
            this.iNewsDa = iNewsDa;
            this.util = util;
        }

        public EditStudyTimeResponse EditStudyTime(EditStudyTimeRequest request)
        {
            var response = new EditStudyTimeResponse();
            var repStudyTime = 0;
            var score = 0;
            var learnTime = 0;
            var result = 0;
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)            
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);            
            var oriScore = util.GetUserInfo(tokens.UserId).Score;
            var studyInfo = new TbUserStudyLog();
            var scoreInfo = iNewsDa.GetNewsDetail(request.NewsId, request.AppId); //新闻学习时间奖励
            if (scoreInfo == null)
                throw new TransactionException(MessageCode.NoData, MessageKey.NoData);
            score = scoreInfo.RewardsScore; //奖励积分
            learnTime = scoreInfo.StudyTime; //满足学习时间
            var title = scoreInfo.Title;
            var resultInfo = iStudyAccess.GetStudyTime(tokens.UserId, request.NewsId, request.ModuleId);
            if (resultInfo == null)
            {
                //insert
                studyInfo.OrgId = tokens.OrgId;
                studyInfo.BranchId = tokens.BranchId;
                studyInfo.UserId = tokens.UserId;
                studyInfo.NewsId = request.NewsId;
                studyInfo.ModuleId = request.ModuleId;
                studyInfo.StudyTime = request.StudyTime;
                studyInfo.CreateTime = DateTime.Now;
                result = iStudyAccess.EditStudyTime(false, studyInfo);
                if (learnTime > 0 && request.StudyTime >= learnTime)
                {
                    util.EditUserScore(tokens.UserId, score);
                    var scoreLs = new TbUserScoreTrace()
                    {
                        OrgId = tokens.OrgId,
                        UserId = tokens.UserId,
                        CreateTime = DateTime.Now,
                        Score = score,
                        RewardsType = "",
                        Comment = "学习获得积分",
                        OriScore = oriScore,
                        Source = title
                    };
                    util.CreateScoreLs(scoreLs); //学习奖励积分
                }
                repStudyTime = request.StudyTime;
            }
            else
            {
                //update
                studyInfo.UserId = tokens.UserId;
                studyInfo.StudyTime = request.StudyTime;
                result = iStudyAccess.EditStudyTime(true, studyInfo);
                var origStudyTime = resultInfo.StudyTime; //原学习时间
                if (learnTime > 0 && origStudyTime < learnTime && (origStudyTime + request.StudyTime >= learnTime)) //原学习时间<满足学习时间 && 原学习时间+本次学习时间>=满足学习时间
                {
                    util.EditUserScore(tokens.UserId, score);
                    var scoreLs = new TbUserScoreTrace()
                    {
                        OrgId = tokens.OrgId,
                        UserId = tokens.UserId,
                        CreateTime = DateTime.Now,
                        Score = score,
                        RewardsType = "",
                        Comment = "学习获得积分",
                        OriScore = oriScore,
                        Source = title
                    };
                    util.CreateScoreLs(scoreLs); //学习奖励积分
                }
                repStudyTime = origStudyTime + request.StudyTime;
            }
            response.StudyTime = repStudyTime;
            return response;
        }

        public GetStudyTimeResponse GetStudyTime(GetStudyTimeRequest request)
        {
            var response = new GetStudyTimeResponse();
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            if (request.AppId <= 0)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            if (!util.CheckAppId(request.AppId))
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            var result = iStudyAccess.GetStudyTime(tokens.UserId, request.NewsId, request.ModuleId);
            if (result != null)
                response.StudyTime = result.StudyTime;
            else
                response.StudyTime = 0;
            return response;
        }

        public GetUserStudyResponse GetUserStudy(GetUserStudyRequest request)
        {
            var response = new GetUserStudyResponse();
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            if (request.AppId <= 0)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            if (!util.CheckAppId(request.AppId))
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            var result = iStudyAccess.GetUserStudy(request.StudyType, tokens.OrgId, tokens.UserId, request.PageIndex, request.PageSize);
            var studyCount = iStudyAccess.GetUserStudyCount(request.StudyType, tokens.OrgId, tokens.UserId);
            response.StudyCount = studyCount;
            response.StudyList = result?.Select(x => new Application.Model.Common.Study()
            {
                NewsId = x.NewsId,
                Module = x.Module,
                ShortDesc = x.ShortDesc,
                Title = x.Title,
                ImageUrl = x.ImageUrl,
                CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm"),
                StudyTime = x.StudyTime
            }).ToList();
            if (result == null || result.Count <= 0)
                throw new TransactionException(MessageCode.NoData, MessageKey.NoData);
            return response;
        }
        
        public GetUserStudyDetailResponse GetUserStudyDetail(GetUserStudyDetailRequest request)
        {
            var response = new GetUserStudyDetailResponse();
            var tokens = util.GetUserId(request.Token, 0);
            if (tokens == null || tokens.UserId <= 0)
                throw new TransactionException(MessageCode.InvalidToken, MessageKey.InvalidToken);
            if (request.AppId <= 0)
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            if (!util.CheckAppId(request.AppId))
                throw new TransactionException(MessageCode.InvalidParameter, MessageKey.InvalidParameter);
            var result = iStudyAccess.GetUserStudyDetail(request.NewsId, request.ModuleId);
            if (result != null)
            {
                response.NewsId = result.NewsId;
                response.Title = result.Title;
                response.HtmlContent = result.HtmlContent;
                response.Author = result.Author;
                response.ImageUrl = result.ImageUrl;
                response.CreateTime = result.CreateTime.ToString("yyyy-MM-dd HH:mm");
                response.StudyTime = result.StudyTime;
            }
            else
                throw new TransactionException(MessageCode.NoData, MessageKey.NoData);
            return response;
        }
    }
}